
#include <BLabel>
#include <BGridLayout>
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BStyle>
#include <BPainter>
#include <BStyle>
#include <BFont>

#include "ShapePanel.h"

ShapePanel::ShapePanel(BWidget* parent) : BGroupBox(parent)
{
	this->setTitle("Shape");

	_materialDialog = new MaterialDialog(this);

	BHBoxLayout* titleLayout = new BHBoxLayout();
	{
		_foldeButton = new BButton();
		_foldeButton->setName("fold");
		_foldeButton->setCheckable(true);
		_foldeButton->setAlign(Align_Center);
		_foldeButton->setForm(Form_IconAlone);
		_foldeButton->setGraph(Graph_Minus);
		_foldeButton->setIconSize(12);

		titleLayout->addWidget(_foldeButton);
		titleLayout->addSpring();
		titleLayout->setMargin(5);
	}
	this->setLayout(titleLayout, Part_Title);

	BGridLayout* gridLayout = new BGridLayout();
	{
		BLabel* visibleLabel = new BLabel("visible");
		_visibleCheckBox = new BCheckBox();

		BLabel* lineWidthLabel = new BLabel("line-width");
		_lineWidthSpinBox = new BSpinBox();

		BLabel* pointSizeLabel = new BLabel("point-size");
		_pointSizeSpinBox = new BSpinBox();

		BLabel* polygonModeLabel = new BLabel("poly-mode");
		_polygonModeComboBox = new BComboBox();
		_polygonModeComboBox->addItem("face", Poly_Fill);
		_polygonModeComboBox->addItem("line", Poly_Line);
		_polygonModeComboBox->addItem("point", Poly_Point);

		gridLayout->setWidget(0, 0, visibleLabel);
		gridLayout->setWidget(0, 1, _visibleCheckBox);
		gridLayout->setWidget(1, 0, lineWidthLabel);
		gridLayout->setWidget(1, 1, _lineWidthSpinBox);
		gridLayout->setWidget(2, 0, pointSizeLabel);
		gridLayout->setWidget(2, 1, _pointSizeSpinBox);
		gridLayout->setWidget(3, 0, polygonModeLabel);
		gridLayout->setWidget(3, 1, _polygonModeComboBox);
		gridLayout->setColumnPolicy(0, Policy_Preferred);
	}

	BVBoxLayout* stateLayout = new BVBoxLayout();
	{
		_lightingCheckBox = new BCheckBox("lighting");
		_cullbackCheckBox = new BCheckBox("cullback");
		_depthTestCheckBox = new BCheckBox("depth-test");
		_pointSmoothCheckBox = new BCheckBox("point-smooth");
		_lineSmoothCheckBox = new BCheckBox("line-smooth");
		_polySmoothCheckBox = new BCheckBox("poly-smooth");
		_transparentCheckBox = new BCheckBox("transparent");

		stateLayout->addWidget(_lightingCheckBox);
		stateLayout->addWidget(_cullbackCheckBox);
		stateLayout->addWidget(_depthTestCheckBox);
		stateLayout->addWidget(_pointSmoothCheckBox);
		stateLayout->addWidget(_lineSmoothCheckBox);
		stateLayout->addWidget(_polySmoothCheckBox);
		stateLayout->addWidget(_transparentCheckBox);
	}

	BHBoxLayout* materialLayout = new BHBoxLayout();
	{
		BLabel* materialLabel = new BLabel("material");
		_materialButton = new BButton();
		_materialButton->setAlign(Align_LeftCenter);
		_colorButton = new BButton(Graph_Square_Fill);

		materialLayout->addWidget(materialLabel, 0);
		materialLayout->addWidget(_materialButton);
		materialLayout->addWidget(_colorButton, 0);
	}

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(gridLayout);
	vlayout->addLayout(stateLayout);
	vlayout->addLayout(materialLayout);

	connect(_foldeButton, Signal_Checked, &ShapePanel::slotFoldeButtonChecked);

	connect(this, Signal_AssetChanged, &ShapePanel::slotAssetChanged);
	connect(_visibleCheckBox, Signal_Toggled, &ShapePanel::slotVisibleToggled);
	connect(_lightingCheckBox, Signal_Toggled, &ShapePanel::slotLightingToggled);
	connect(_lineWidthSpinBox, Signal_ValueEdited, &ShapePanel::slotLineWidthEdited);
	connect(_pointSizeSpinBox, Signal_ValueEdited, &ShapePanel::slotPointSizeEdited);
	connect(_polygonModeComboBox, Signal_ItemClicked, &ShapePanel::slotPolygonModeToggled);

	connect(_cullbackCheckBox, Signal_Toggled, &ShapePanel::slotCullbackToggled);
	connect(_depthTestCheckBox, Signal_Toggled, &ShapePanel::slotDepthTestToggled);
	connect(_pointSmoothCheckBox, Signal_Toggled, &ShapePanel::slotPointSmoothToggled);
	connect(_lineSmoothCheckBox, Signal_Toggled, &ShapePanel::slotLineSmoothToggled);
	connect(_polySmoothCheckBox, Signal_Toggled, &ShapePanel::slotPolygonSmoothToggled);
	connect(_transparentCheckBox, Signal_Toggled, &ShapePanel::slotTransparentToggled);
	connect(_materialButton, Signal_Clicked, &ShapePanel::slotMaterialButtonClicked);
	connect(_colorButton, Signal_Clicked, &ShapePanel::slotColorButtonClicked);

	this->setEnabled(false);
}
ShapePanel::~ShapePanel()
{

}

void ShapePanel::slotAssetChanged(BObject* object, const BValue& value)
{
	BShape* shape = value;
	if (_shape != shape)
	{
		_shape = shape;
		if (_shape)
		{
			_visibleCheckBox->setChecked(shape->visible());
			_lineWidthSpinBox->setValue(_shape->lineWidth());
			_pointSizeSpinBox->setValue(_shape->pointSize());
			_polygonModeComboBox->setValue(_shape->polyMode());
			_lightingCheckBox->setChecked(_shape->lighting());
			_cullbackCheckBox->setChecked(_shape->cullback());
			_depthTestCheckBox->setChecked(_shape->depthTest());
			_pointSmoothCheckBox->setChecked(_shape->pointSmooth());
			_lineSmoothCheckBox->setChecked(_shape->lineSmooth());
			_polySmoothCheckBox->setChecked(_shape->polygonSmooth());
			_transparentCheckBox->setChecked(_shape->transparent());
			if (BImage* image = dynamic_cast<BImage*>(_shape->texture()))
			{
				_materialButton->setImage(image);
				_materialButton->setText(image->fileName());
			}
			_colorButton->setColor(_shape->color());
		}
		_materialDialog->setAsset(_shape);
		this->setEnabled(shape);
	}
}
void ShapePanel::slotFoldeButtonChecked(const BObject* object, const BValue& value)
{
	bool checked = value;
	if (checked)
		_foldeButton->setGraph(Graph_Plus);
	else
		_foldeButton->setGraph(Graph_Minus);
	if (checked)
	{
		if (BLayout* layout = this->layout(Part_Center))
			layout->setEnabled(false);
		if (BLayout* layout = this->layout(Part_Bottom))
			layout->setEnabled(false);
		if (BLayout* layout = this->layout(Part_Left))
			layout->setEnabled(false);
		if (BLayout* layout = this->layout(Part_Right))
			layout->setEnabled(false);
		this->setPerch(Part_Bottom, 0);
	}
	else
	{
		if (BLayout* layout = this->layout(Part_Center))
			layout->setEnabled(true);
		if (BLayout* layout = this->layout(Part_Bottom))
			layout->setEnabled(true);
		if (BLayout* layout = this->layout(Part_Left))
			layout->setEnabled(true);
		if (BLayout* layout = this->layout(Part_Right))
			layout->setEnabled(true);
		int titleHeight = this->perch(Part_Title);
		this->setPerch(Part_Bottom, titleHeight / 2);
	}
	emit("folded", checked);
	this->adjust();
}
void ShapePanel::slotVisibleToggled(BObject* object, const BValue& value)
{
	bool visible = _visibleCheckBox->checked();
	_shape->setVisible(visible);
	emit("change-shape", _shape);
}
void ShapePanel::slotLineWidthEdited(BObject* object, const BValue& value)
{
	int lineWidth = value;
	_shape->setLineWidth(lineWidth);
	emit("change-shape", _shape);
}
void ShapePanel::slotPointSizeEdited(BObject* object, const BValue& value)
{
	int pointSize = value;
	_shape->setPointSize(pointSize);
	emit("change-shape", _shape);
}
void ShapePanel::slotPolygonModeToggled(BObject* object, const BValue& value)
{
	BComboItem* item = value;
	_shape->setPolyMode(item->value());
	emit("change-shape", _shape);
}

void ShapePanel::slotLightingToggled(BObject* object, const BValue& value)
{
	bool checked = value;
	_shape->setLighting(checked);
	emit("change-shape", _shape);
}
void ShapePanel::slotCullbackToggled(BObject* object, const BValue& value)
{
	bool cullback = value;
	_shape->setCullback(cullback);
	emit("change-shape", _shape);
}
void ShapePanel::slotDepthTestToggled(BObject* object, const BValue& value)
{
	bool depthTest = value;
	_shape->setDepthTest(depthTest);
	emit("change-shape", _shape);
}
void ShapePanel::slotPointSmoothToggled(BObject* object, const BValue& value)
{
	bool pointSmooth = value;
	_shape->setPointSmooth(pointSmooth);
	emit("change-shape", _shape);
}
void ShapePanel::slotLineSmoothToggled(BObject* object, const BValue& value)
{
	bool lineSmooth = value;
	_shape->setLineSmooth(lineSmooth);
	emit("change-shape", _shape);
}
void ShapePanel::slotPolygonSmoothToggled(BObject* object, const BValue& value)
{
	bool polygonSmooth = value;
	_shape->setPolygonSmooth(polygonSmooth);
	emit("change-shape", _shape);
}
void ShapePanel::slotTransparentToggled(BObject* object, const BValue& value)
{
	bool transparent = value;
	_shape->setTransparent(transparent);
	emit("change-shape", _shape);
}
void ShapePanel::slotMaterialButtonClicked()
{
	_materialDialog->popup();
}
void ShapePanel::slotColorButtonClicked()
{
	BColor color = BColorDialog::ChooseColor("Choose Color for Shape", _shape->color());
	_shape->setColor(color);
	_colorButton->setColor(color);
	emit("change-shape", _shape);

}

void ShapePanel::styleEvent(const BEvent& event)
{
	BGroupBox::styleEvent(event);
	if (const BStyle* style = this->realStyle())
	{

	}
}
void ShapePanel::paintEvent(const BEvent& event)
{
	BGroupBox::paintEvent(event);
}
